home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_10 / 9n10126a < prev    next >
Text File  |  1991-08-10  |  5KB  |  202 lines

  1. /*********************************************************
  2.  *    MAXL.C: Analyze line lengths to help slim down 
  3.  *        code listings for publications such as CUJ
  4.  *    Written by Leor Zolman, 12/89, 2/91
  5.  *    What it does:    
  6.  *    Scans the input file, keeping track of the number of
  7.  *    lines of each varying length encountered.
  8.  *    Displays first instance of each of the n longest
  9.  *    line lengths encountered, along with frequency.
  10.  *    Hard tab interpretation may be set to any value.
  11.  *
  12.  *    Usage: maxl [-t#] [-d%] [-f$] filename
  13.  *      # = soft tab setting (defaults to 4)
  14.  *      % = how many different lengths to display (def. 3)
  15.  *      $ = flag lines longer than this length (def. 79)
  16.  *  Compile:
  17.  *        Borland C:
  18.  *            bcc maxl.c
  19.  *        Xenix C:
  20.  *            cc maxl.c -o maxl
  21.  ********************************************************/
  22.  
  23.  
  24. #include <stdio.h>
  25.  
  26. #define MAXLINE 300            /* longest allowable line    */
  27. #define DEFAULT_TAB    4        /* default soft tab setting */
  28. #define DIFF_SIZES    3        /* # of diff. sizes to show    */
  29. #define DEF_FLAG    79        /* flag lines longer than...*/
  30.  
  31. void putrule(int);            /* draw a horizontal line    */
  32. void putline(char *, int);
  33.  
  34. struct line {
  35.     int first;                /* line # of first instance    */
  36.     char *text;                /* the text of 1st instance    */
  37.     int how_many;            /* # of lines that length    */
  38. } lines[MAXLINE];            /* one for each length        */
  39.  
  40. int tabstop = DEFAULT_TAB;
  41. int diffsizes = DIFF_SIZES;
  42. int flaglen = DEF_FLAG;
  43.  
  44. void main(argc, argv)
  45. int argc;
  46. char **argv;
  47. {
  48.     int v_col;                /* virtual column number        */
  49.     int lineno;                /* line number of current line    */
  50.     char lbuf[MAXLINE];        /* input line buffer            */
  51.     char c, *lp;
  52.     FILE *fp;
  53.     int i, j;
  54.     
  55.     for (i = 1; i < argc; i++)
  56.         if (argv[i][0] == '-')
  57.         {
  58.             switch (tolower(argv[i][1]))
  59.             {
  60.                 case 't':    tabstop = atoi(&argv[i][2]);
  61.                             break;
  62.  
  63.                 case 'd':    diffsizes = atoi(&argv[i][2]);
  64.                             break;
  65.  
  66.                 case 'f':    flaglen = atoi(&argv[i][2]);
  67.                             break;
  68.  
  69.                 default:    printf("Unknown option: '%s'\n", 
  70.                                     argv[i]);
  71.                             exit(0);
  72.             }
  73.             for (j = i; j < argc - 1; j++)
  74.                 argv[j] = argv[j + 1];
  75.             argc--;
  76.             i--;
  77.         }
  78.  
  79.     if (argc != 2)
  80.     {
  81.         fprintf(stderr,
  82.           "Usage:  %s [-t#] [-d#] [f#] file\n",  argv[0]);
  83.         fprintf(stderr,
  84.             "-t#: Set hard tab value\n");
  85.         fprintf(stderr,
  86.             "-d#: Set number of different lengths to show\n");
  87.         fprintf(stderr,
  88.             "-f#: Flag lines longer than # characters\n");
  89.         exit(1);
  90.     }
  91.     
  92.     if ((fp = fopen(argv[1], "r")) == NULL)
  93.         exit(printf("Can't open %s for input.\n", argv[1]));
  94.     
  95.     for (i = 0; i <= MAXLINE; i++)
  96.         lines[i].how_many = 0;        /* none found yet            */
  97.     lineno = 1;
  98.  
  99.     while (fgets(lbuf, MAXLINE, fp) != NULL)
  100.     {
  101.         v_col = 1;                    /* track virtual column #    */
  102.         for (lp = lbuf; c = *lp; lp++)
  103.         {
  104.             if (c == '\n')            /* newline is end of line    */
  105.                 break;
  106.             
  107.             if (c == '\t')            /* tab is interpreted as a    */
  108.                 while (v_col++ % tabstop)    /* # of spaces    */
  109.                     ;
  110.             else if (c == '\r')        /* CR sans newline is a    */
  111.             {                        /* special twisted case    */
  112.                 fprintf(stderr,
  113.                   "WARNING: CR before newline in line %d\n",
  114.                             lineno);
  115.                 v_col = 1;            /* back to the left margin    */
  116.             }
  117.             else
  118.                 v_col++;            /* all printing chars        */
  119.         }
  120.         v_col--;                    /* adjust to ending col. #    */
  121.         if (v_col >= flaglen)
  122.             fprintf(stderr, 
  123.                 "\aLine #%d: %d columns exceeds maximum (%d)\n",
  124.                         lineno, v_col , flaglen);
  125.                                     /* bump counter for length    */
  126.         if (!lines[v_col].how_many++)    /* first time for    */
  127.         {                        /* this length? if so...    */
  128.             lines[v_col].first = lineno;    /* save line #,    */
  129.             if ((lines[v_col].text =        /* & save text    */
  130.                 (char *) malloc(strlen(lbuf) + 1)) == NULL)
  131.             {
  132.                 fprintf(stderr,
  133.                     "Out of memory in line %d\n", lineno);
  134.                 exit(1);
  135.             }
  136.             strcpy(lines[v_col].text, lbuf);
  137.         }
  138.         lineno++;
  139.     }
  140.     
  141.     printf("\n");
  142.     j = 0;                            /* # of diff. lengths shown        */
  143.     for (i = MAXLINE - 1; i > 0; i--)            /* display results    */
  144.     {
  145.         if (!lines[i].how_many)
  146.             continue;
  147.         printf("Length: %d    First instance: line #%d",
  148.                 i, lines[i].first);
  149.         printf("   Quantity: %d\n", lines[i].how_many);
  150.         putline(lines[i].text, i);
  151.         if (++j == diffsizes)
  152.             break;
  153.         printf("\n");
  154.     }
  155.     fclose(fp);
  156. }
  157.  
  158.  
  159. /*
  160.  * putline(): Display a line of text, with rule line 
  161.  *              before and after
  162.  */
  163.  
  164. void putline(line, length)
  165. char *line;
  166. int length;
  167. {
  168.     char *lp, c;
  169.     int v_col;
  170.     
  171.     putrule(length);
  172.     for (lp = line, v_col = 1; c = *lp; lp++)
  173.         switch (c)
  174.         {
  175.             case '\t':            /* translate tabs to spaces */
  176.                 do 
  177.                     putchar(' ');
  178.                 while (v_col++ % tabstop);
  179.                 break;
  180.             default:
  181.                 putchar(c);
  182.                 v_col++;
  183.         }
  184.     putrule(length);
  185. }
  186.  
  187.  
  188. /*
  189.  * putrule(): display a horizontal line so trailing 
  190.  *              whitespace is detectable
  191.  */
  192.  
  193. void putrule(ncols)
  194. int ncols;
  195. {
  196.     int i;
  197.  
  198.     for (i = 0; i < ncols; i++)
  199.         putchar('=');
  200.     putchar('\n');
  201. }
  202.